package main

import (
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"github.com/vmihailenco/msgpack/v5"
	"go.uber.org/zap"
	"gogogo-server/engine/utils"
	"gogogo-server/gameserver/global"
	"gogogo-server/gameserver/handlers"
	"gogogo-server/gameserver/initialize"
	"gogogo-server/gameserver/model"
	"gogogo-server/gameserver/protocols"
	"gogogo-server/gameserver/service"
	"log"
	"net/http"
)

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true // 允许任何来源的WebSocket连接
	},
}

func handleWebSocket(c *gin.Context) {
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		zap.S().Warnf("升级websocket出错:%s,ip:%s", err, c.ClientIP())
		c.JSON(http.StatusBadGateway, gin.H{
			"msg": "升级websocket失败",
		})
		return
	}
	clientIp := c.ClientIP()
	zap.S().Infof("有新的连接上来,ip:%s", clientIp)
	defer conn.Close()

	roleBasicInfo := &handlers.RoleBasicInfo{
		SendMsgChan: make(chan string),
	}
	go func() {
		for msg := range roleBasicInfo.SendMsgChan {
			if sendErr := conn.WriteMessage(1, []byte(msg)); sendErr != nil { // 发送失败可能是断开连接了
				zap.S().Infof("角色:%d 发送消息失败:%s,断开连接", roleBasicInfo.RoleUid, sendErr)
				break
			}
		}
	}()

	for {
		_, message, err := conn.ReadMessage()
		if err != nil {
			log.Println("Read Error:", err)
			break
		}
		if string(message) == "login" {
			handlers.TryVerifyLogin("token", roleBasicInfo)
			roleBasicInfo.SendMsgChan <- "角色账号:" + roleBasicInfo.Account
			continue
		}
		var msg = &protocols.Message{}
		if err = msgpack.Unmarshal(message, msg); err != nil {
			zap.S().Warnf("客户端:%s 处理消息序列化出错:%s", clientIp, err)
			continue
		}
		// 路由到相应的处理器
		zap.S().Debugf("客户端:%s 收到消息类型:%s", clientIp, msg.Event)
		if len(roleBasicInfo.Account) == 0 { // 第一步只能是验证并加载角色
			if msg.Event == "login" { // 符合预期的第一步是登录验证
				handlers.TryVerifyLogin("token", roleBasicInfo)
				// TODO 失败处理
			} // 不符合预期,请先登录
			roleBasicInfo.SendMsgChan <- "请先登录"
		} else {
			if msg.Event == "login" { // 重复登录
				roleBasicInfo.SendMsgChan <- "重复登录"
			}
			handlers.OnReceiveClientMsg(roleBasicInfo.RoleUid, msg)
		}
	}
	close(roleBasicInfo.SendMsgChan)
}

func init() {
	if err := utils.ParseYaml("config/game.yaml", &global.GGG_CONFIG); err != nil {
		log.Fatal("加载配置失败:", err)
	}
	if err := initialize.TryInitialize(); err != nil {
		log.Fatal("初始化失败:", err)
	}
	initialize.InitRedis()
	//uniTest()
}

func uniTest() {
	player := &model.Player{
		ID:       1,
		Diamonds: 1000,
		Coins:    1000,
		Level:    1,
	}
	playerService := service.DataService.GetPlayerService()
	exists, err := playerService.ExistsByID(player.ID)
	if err != nil {
		// 处理错误
	}
	if !exists {
		err = playerService.Create(player)
		if err != nil {
			return
		}
	}
	player, err = playerService.GetByID(player.ID)
	if err != nil {
		return
	}
	zap.S().Info(player.Coins)
	player.Coins += 3000
	err = playerService.Save(player)
	if err != nil {
		return
	}
	player, err = playerService.GetByID(player.ID)
	zap.S().Info(player.Coins)
}

func main() {
	zap.S().Info("Start server")
	zap.S().Debug(global.GGG_CONFIG)
	handlers.InitMessageHandlers()
	r := gin.Default()
	r.GET("/", handleWebSocket)
	zap.S().Fatal(r.Run(global.GGG_CONFIG.ListenAddr))
}
